package info.hexin.ioc.loader.impl;

import info.hexin.ioc.IocBean;
import info.hexin.ioc.Property;
import info.hexin.ioc.annotation.Scope;
import info.hexin.ioc.loader.Loader;
import info.hexin.lang.Assert;
import info.hexin.log.Log;
import info.hexin.log.Logs;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 按照xml格式加载类
 * 
 * @author hexin
 * 
 */
public class XmlLoader implements Loader {
    private static final Log log = Logs.get();
    private Map<String, IocBean> beanMap = new HashMap<String, IocBean>();

    public XmlLoader(String... xmls) {
        try {
            for (String xmlFile : xmls) {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                InputStream inputStream = XmlLoader.class.getClassLoader().getResourceAsStream(xmlFile);
                Assert.notNull(inputStream);
                Document document = builder.parse(inputStream);
                NodeList rootList = document.getElementsByTagName("beans");
                if (rootList == null || rootList.getLength() == 0) {
                    log.error("xml config file :" + xmlFile + " not find beans tag !");
                    continue;
                }

                Element root = (Element) rootList.item(0);
                NodeList beanList = root.getElementsByTagName("bean");
                for (int i = 0; i < beanList.getLength(); i++) {
                    IocBean iocBean = new IocBean();
                    Element beanNode = (Element) beanList.item(i);
                    String beanId = beanNode.getAttribute("id");
                    String clazzName = beanNode.getAttribute("class");
                    String scopeName = beanNode.getAttribute("scope");
                    iocBean.setName(beanId);
                    iocBean.setClassName(clazzName);
                    iocBean.setScope(Scope.of(scopeName));

                    // property
                    NodeList propertyNodes = beanNode.getElementsByTagName("property");
                    for (int k = 0; k < propertyNodes.getLength(); k++) {
                        Element propertyNode = (Element) propertyNodes.item(i);
                        String propertyName = propertyNode.getAttribute("name");
                        String propertyValue = propertyNode.getAttribute("value");
                        String propertyRef = propertyNode.getAttribute("ref");
                        Property property = new Property();
                        property.setName(propertyName);
                        property.setRef(propertyRef);
                        property.setValue(propertyValue);
                        iocBean.addProperty(property);
                    }
                    beanMap.put(beanId, iocBean);
                }
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            // 可能为空
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, IocBean> getBeans() {
        return beanMap;
    }
}
